[Day 07]: Dockerfile 初探



建構映像

Docker 提供一種透過設定檔來建立映像的方式
即以 Dockerfile建構映像,這種方式是將製作映像的動作全部寫入一個檔案之中

優點:獨立、透明、建構方式容易重複執行、可方便移植

Dockerfile

  • 沒有副檔名,為純粹的文字檔
  • 形式:

    • 註解:在 Dockerfile中,註解的開頭皆以 # 起頭
    • 指令:(通常以大寫為主,方便區分)
      • Instruction:指令名稱
      • Argument: 指令參數
    • 例外:某類特定參數的開頭也為 #
      # directive=value,為解析指令列,用以提供解析Dockerfile所需要的參數

Dockerfile 範例

使用Dockerfile建構映像

docker CLI提供docker build命令,按照dockerfile內容輕鬆建立對應的映像

* docker build ~/Redis

// 建立 Redis映像
// build所接收的參數,必須為存放dockerfile的 「目錄」
//若存放 dockerfile的檔名非稱為"dockerfile",則加入參數 -f 放入目標路徑

docker會根據dockerfile建立映像時的每個步驟都產生一個映像,在建立映像時,docker會先在本地端查看使否已有該映像,若已存在則直接使用;這種逐一產生映像的方式對應了先前所說的映像中的分層結構,每層都是上一層的提交~

若不想要有太多層映像,可善用 && 將指令合併

建立映像時,必須指定映像的名稱和標籤

* docker build -t Kevin/redis:latest ~/Redis

// -t, tag

dockerfile指令

From

  • 用來指定建置的映象是基於哪個映像而來,這樣就不必每個映像都從頭開始建構
* FROM <Image>
* FROM <Image>:<Tag>
* FROM <Image>@<digest>

Maintainer

  • 提供映像的作者資訊
* MAINTAINER <Name>

Run

  • 即跑指令,為dockerfile中最常用的指令,指令有兩種模式
* RUN command param1 param2 ...                 // 1.
* RUN ["executable","param1","param2",...]      // 2.

指令1表示,建構映像時,實際上是以Shell來執行操作,

例如: RUN mkdir data 會是以 /bin/sh -c mkdir data

為何必須由Shell來操作呢?重點是:支援換列,可以使用「\」以拆解命令

* RUN apt-get install -y \
           file \
           g++ \
           gcc \
           make \
           curl \
           libc-dev \
           ...

而指令2會在命令和參數包在雙引號內,若某些基礎映像沒有使用Shell,這個指令模式則派上用場

* RUN ["/bin/bash", "-c","echo hello"]

Workdir

  • 用來切換建構過程的工作目錄
* WORKDIR /usr
// 可使用絕對目錄或相對目錄
* WORKDIR local
  • 亦允許使用環境變數
* ENV BASEDIR /project
* WORKDIR $BASEDIR/www

Onbuild

  • 特殊指令,可攜帶另一道指令
  • 可以看成一個觸發器,onbuild 所接的指令不會在建構時被執行
  • 但若其他Dockerfile 把此映像作為基礎映像並建置時,在執行完FORM指令後,所有透過Onbuild指令設定的指令將被觸發
* ONBUILD  INSTRUCTION arguments

Add

  • 建構映像時,常常需要將一些設定檔、執行腳本匯入映像的建置過程,此時就可以透過add指令將檔案從外部傳遞到映像內部
* ADD <src> .. <dest>
* ADD ["<src>",..."<dest>"]
// 將 src 目錄中的檔案 複製到 dest 映像的目標路徑

Copy

  • 此為另一種引入檔案的方式
* COPY <src>...<dest>
* COPY ["<src>",..."<dest>"]

CMD

  • dockerfile中可透過CMD指令來指定由映像建立的容器內的主體程式
* CMD ["executable","param1","param2",...]
* CMD ["param1","param2",...]
* CMD command param1 param2 ...

Entrypoint

  • 映像內應用程式運作時,多少都會有系統服務以及其他程式的支援
  • CMD啟動服務後,啟動支援服務的命令和主程式的命令混雜十分混亂
  • 透過ENTRYPOINT負責主程式執行前的準備工作
* ENTRYPOINT ["executable","param1","param2",...]
* ENTRYPOINT command param1 param2 ....

ENTRYPOINT指定的命令,都不會在容器啟動時執行,而是把這些命令作為參數傳入ENTRYPOINT指令列出的程式當中

Expose

  • 容器間的通訊必須透過docker來轉發
  • 若應用程式允許被其他映像存取它所提供的連接埠,則需列出對外開放的port號
* EXPOSE <port> [<port>...]

ENV

  • 設定環境變數
* ENV <key> <value>
* ENV <key>=<value>...

以上則為dockerfile 語法初探
7 天帶你對docker有基本認識
這 7天系列文,也算是小弟對 docker研究 7天下來的筆記
資訊若有誤,懇請糾正 <(_ _)>


參考資料

[1]
https://zhuanlan.zhihu.com/p/33366306

#docker #dockerfile #虛擬化技術







你可能感興趣的文章

DOM 相關筆記

DOM 相關筆記

How to build CICD with Jenkins as code based on container

How to build CICD with Jenkins as code based on container

程式基礎 —— Javascript

程式基礎 —— Javascript






留言討論